// Rust学习智能体前端应用
class RustLearningApp {
    constructor() {
        this.currentUserId = '';
        this.sessionId = '';
        this.isLoading = false;
        this.currentChallenge = null;
        this.challengeProgress = {};
        this.currentTopic = 'all';
        
        // 挑战系统相关变量
        this.challengesData = null;
        this.currentTopicForChallenge = null;
        this.currentLevelIndex = 0;
        this.draggedElement = null;
        this.init();
    }
    
    // 复制代码到剪贴板
    copyToClipboard(button) {
        const codeBlock = button.closest('.code-block');
        const codeElement = codeBlock.querySelector('code');
        const text = codeElement.textContent;
        
        navigator.clipboard.writeText(text).then(() => {
            const originalHTML = button.innerHTML;
            button.innerHTML = '<i class="fas fa-check"></i> 已复制';
            button.style.backgroundColor = 'rgba(40, 167, 69, 0.2)';
            button.style.borderColor = '#28a745';
            button.style.color = '#28a745';
            
            setTimeout(() => {
                button.innerHTML = originalHTML;
                button.style.backgroundColor = '';
                button.style.borderColor = '';
                button.style.color = '';
            }, 2000);
        }).catch(err => {
            console.error('复制失败:', err);
            button.innerHTML = '<i class="fas fa-times"></i> 复制失败';
            setTimeout(() => {
                button.innerHTML = originalHTML;
            }, 2000);
        });
    }

   async init() {
        this.loadUserSession();
        this.initMermaid();
        this.bindEvents();
        await this.loadTopics();
        await this.loadChartTypes();
        await this.loadChallenges();
        this.showWelcomeMessage();
        this.initMobileMenu();
        this.initAnimations();
        this.initChallenges();
    }

    bindEvents() {
        // Chat functionality
        const sendButton = document.getElementById('send-button');
        if (sendButton) {
            sendButton.addEventListener('click', () => this.sendMessage());
        }
        
        const messageInput = document.getElementById('message-input');
        if (messageInput) {
            messageInput.addEventListener('keypress', (e) => {
                if (e.key === 'Enter' && !e.shiftKey) {
                    e.preventDefault();
                    this.sendMessage();
                }
            });
        }
        
        // Visualization functionality
        const generateButton = document.getElementById('generate-button');
        if (generateButton) {
            generateButton.addEventListener('click', () => this.generateVisualization());
        }
        
        // Challenge functionality
        const topicFilter = document.getElementById('topic-filter');
        if (topicFilter) {
            // topic-filter is a div, not a select, so we need to add click listeners to its children
            topicFilter.addEventListener('click', (e) => {
                if (e.target.classList.contains('topic-btn')) {
                    const topic = e.target.dataset.topic;
                    this.filterChallenges(topic);
                }
            });
        }
        
        const validateBtn = document.getElementById('validate-btn');
        if (validateBtn) {
            validateBtn.addEventListener('click', () => this.validateChallenge());
        }
        
        const nextChallengeBtn = document.getElementById('next-challenge-btn');
        if (nextChallengeBtn) {
            nextChallengeBtn.addEventListener('click', () => {
                this.closeChallenge();
                this.loadChallenges();
            });
        }
        
        // Modal close button
        const closeModalBtn = document.querySelector('.close-modal');
        if (closeModalBtn) {
            closeModalBtn.addEventListener('click', () => {
                this.closeChallenge();
            });
        }
        
        // Tab switching
        document.querySelectorAll('.tab-button').forEach(btn => {
            btn.addEventListener('click', (e) => {
                // 检查元素是否存在
                if (!e.target || !e.target.classList) return;
                
                const targetButton = e.target;
                const tabId = targetButton.dataset.tab;
                
                if (!tabId) return;
                
                // 移除所有active类
                document.querySelectorAll('.tab-button').forEach(b => {
                    if (b && b.classList) b.classList.remove('active');
                });
                document.querySelectorAll('.tab-content').forEach(c => {
                    if (c && c.classList) c.classList.remove('active');
                });
                
                // 添加active类
                targetButton.classList.add('active');
                const targetTab = document.getElementById(`${tabId}-tab`);
                if (targetTab && targetTab.classList) {
                    targetTab.classList.add('active');
                    // Add animation effect
                    this.animateTabContent(targetTab);
                }
            });
        });
        
        // Knowledge cards click events
        document.querySelectorAll('.knowledge-card').forEach(card => {
            card.addEventListener('click', () => {
                const topic = card.dataset.topic;
                this.askQuestion(`请详细介绍Rust的${this.getTopicDisplayName(topic)}`);
            });
        });
        
        // Sidebar questions click events
        document.querySelectorAll('.sidebar-question').forEach(question => {
            question.addEventListener('click', () => {
                const questionText = question.textContent.trim();
                this.askQuestion(questionText);
            });
        });
        
        // Suggestion buttons click events
        document.querySelectorAll('.suggestion-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                const question = btn.dataset.question;
                this.askQuestion(question);
            });
        });
        
        // Drag and drop for challenges
        this.initDragAndDrop();
    }

    // Chat functionality
    async sendMessage() {
        const messageInput = document.getElementById('message-input');
        const message = messageInput.value.trim();

        if (!message) return;

        // 隐藏欢迎界面，显示聊天容器
        this.hideWelcomeAndShowChat();
        
        this.addMessage(message, 'user');
        messageInput.value = '';
        this.setLoading(true);

        try {
            const response = await this.callBackendAPI('/api/chat', {
                user_id: this.currentUserId || 'web_user',
                message: message
            });
            
            if (response.status === 'success') {
                this.addMessage(response.answer_markdown || response.answer, 'assistant');
                
                // 根据问题分类显示不同的反馈
                if (response.classification && response.classification.label) {
                    this.showClassificationFeedback(response.classification);
                }
            } else {
                this.addMessage(`抱歉，处理您的问题时出现错误：${response.message}`, 'assistant');
            }
        } catch (error) {
            console.error('API调用错误:', error);
            this.addMessage('抱歉，网络连接出现问题，请稍后重试。', 'assistant');
        } finally {
            this.setLoading(false);
        }
    }
    
    hideWelcomeAndShowChat() {
        const welcomeContainer = document.getElementById('chat-welcome');
        const messagesContainer = document.getElementById('messages-container');
        
        if (welcomeContainer && messagesContainer) {
            welcomeContainer.style.display = 'none';
            messagesContainer.style.display = 'flex';
        }
    }
    
    showClassificationFeedback(classification) {
        // 根据问题分类显示不同的反馈
        const feedbackMap = {
            'greeting': '您好！我是Rust学习助手，很高兴为您服务！',
            'definition': '这是一个概念性问题，希望我的解释对您有帮助！',
            'usage': '这是一个使用方法问题，您可以尝试运行示例代码加深理解。',
            'error_debug': '这是一个调试问题，建议您仔细检查错误信息和代码逻辑。',
            'comparison': '这是一个比较性问题，理解它们的区别对掌握Rust很重要。',
            'faq': '这是一个常见问题，希望我的回答能够解决您的疑惑。'
        };
        
        const feedback = feedbackMap[classification.label];
        if (feedback && classification.confidence > 0.7) {
            // 可以在界面上显示这个反馈，例如作为提示或通知
            console.log(feedback);
        }
    }

    getTopicDisplayName(topic) {
        // 将英文主题名转换为中文显示名
        const topicMap = {
            'ownership': '所有权系统',
            'borrowing': '借用检查器',
            'lifetimes': '生命周期',
            'traits': 'Trait系统',
            'error-handling': '错误处理',
            'concurrency': '并发编程',
            'macros': '宏系统',
            'async': '异步编程'
        };
        return topicMap[topic] || topic;
    }

    askQuestion(question) {
        const messageInput = document.getElementById('message-input');
        const chatTab = document.querySelector('[data-tab="chat"]');
        
        // Switch to chat tab safely
        document.querySelectorAll('.tab-button').forEach(btn => {
            if (btn.classList) btn.classList.remove('active');
        });
        document.querySelectorAll('.tab-content').forEach(content => {
            if (content.classList) content.classList.remove('active');
        });
        if (chatTab && chatTab.classList) {
            chatTab.classList.add('active');
        }
        const chatTabContent = document.getElementById('chat-tab');
        if (chatTabContent && chatTabContent.classList) {
            chatTabContent.classList.add('active');
        }
        
        // Set question and send
        if (messageInput) {
            messageInput.value = question;
            this.sendMessage();
        }
    }

    async callBackendAPI(endpoint, data = null) {
        // Determine if this is a GET or POST request
        const isGetRequest = endpoint === '/api/topics' || 
                            endpoint === '/api/chart_types' || 
                            endpoint === '/api/challenges';
        
        let options = {
            method: isGetRequest ? 'GET' : 'POST',
            headers: { 'Content-Type': 'application/json' }
        };
        
        // Only add body for POST requests
        if (!isGetRequest && data) {
            options.body = JSON.stringify(data);
        }
        
        // For GET requests with data, append as query parameters
        if (isGetRequest && data) {
            const params = new URLSearchParams();
            Object.keys(data).forEach(key => {
                params.append(key, data[key]);
            });
            endpoint += `?${params.toString()}`;
        }
        
        const response = await fetch(endpoint, options);
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        return await response.json();
    }

    addMessage(content, sender) {
        const messagesContainer = document.getElementById('messages-container');
        const messageDiv = document.createElement('div');
        messageDiv.className = `message ${sender}-message`;
        
        // 创建头像元素
        const avatarDiv = document.createElement('div');
        avatarDiv.className = 'message-avatar';
        
        // 设置头像图标和样式
        if (sender === 'user') {
            // 用户头像 - 使用用户图标
            avatarDiv.innerHTML = '<i class="fas fa-user"></i>';
            avatarDiv.style.background = 'linear-gradient(135deg, #ff6b6b, #ff8e8e)';
        } else {
            // 机器人头像 - 使用机器人图标
            avatarDiv.innerHTML = '<i class="fas fa-robot"></i>';
            avatarDiv.style.background = 'linear-gradient(135deg, #4facfe, #00f2fe)';
        }
        
        let messageContentHTML;
        if (sender === 'assistant') {
            messageContentHTML = this.renderMarkdown(content);
        } else {
            const tempDiv = document.createElement('div');
            tempDiv.textContent = content;
            messageContentHTML = tempDiv.innerHTML;
        }

        // 创建消息内容容器
        const contentDiv = document.createElement('div');
        contentDiv.className = 'message-content';
        contentDiv.innerHTML = messageContentHTML;
        
        // 将头像和内容添加到消息容器中
        messageDiv.appendChild(avatarDiv);
        messageDiv.appendChild(contentDiv);
        
        messagesContainer.appendChild(messageDiv);
        messagesContainer.scrollTop = messagesContainer.scrollHeight;

        if (sender === 'assistant') {
            this.processMessageContent(messageDiv);
        }
    }

    renderMarkdown(content) {
        // 先提取所有的代码块，避免它们被其他处理影响
        const codeBlocks = [];
        let processedContent = content.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
            const language = lang || 'rust';
            // 清理代码内容，保留原始格式但确保正确的换行
            const cleanCode = code
                .replace(/\r\n/g, '\n')  // 统一换行符
                .replace(/\n+$/, '\n')   // 移除末尾多余换行
                .replace(/^\n+/, '');    // 移除开头多余换行
            
            const codeBlockId = `codeblock-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
            codeBlocks.push({
                id: codeBlockId,
                language: language,
                code: cleanCode
            });
            
            return `__CODE_BLOCK_PLACEHOLDER_${codeBlockId}__`;
        });

        // 处理其他Markdown元素
        let html = processedContent
            // 处理标题 (###, ##, #)
            .replace(/^### (.*$)/gim, '<h3>$1</h3>')
            .replace(/^## (.*$)/gim, '<h2>$1</h2>')
            .replace(/^# (.*$)/gim, '<h1>$1</h1>')
            // 处理内联代码
            .replace(/`([^`]+)`/g, '<code class="inline-code">$1</code>')
            // 处理粗体
            .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
            // 处理斜体
            .replace(/\*(.*?)\*/g, '<em>$1</em>')
            // 处理换行 - 先处理双换行（段落分隔）
            .replace(/\n\n+/g, '</p><p>')
            // 处理单换行（但不在代码块占位符中）
            .replace(/\n/g, '<br>');
        
        // 替换代码块占位符为实际的HTML结构
        codeBlocks.forEach(block => {
            const escapedCode = this.escapeHtml(block.code);
            const codeBlockHTML = `<div class="code-block">
                <div class="code-header">
                    <span class="code-language">${block.language}</span>
                    <button class="copy-button" onclick="app.copyToClipboard(this)">
                        <i class="fas fa-copy"></i> 复制
                    </button>
                </div>
                <pre class="code-pre"><code class="language-${block.language}">${escapedCode}</code></pre>
            </div>`;
            
            html = html.replace(new RegExp(`__CODE_BLOCK_PLACEHOLDER_${block.id}__`, 'g'), codeBlockHTML);
        });
        
        // 如果内容不以特定标签开头，则包装在<p>标签中
        if (!html.startsWith('<h1>') && !html.startsWith('<h2>') && !html.startsWith('<h3>') && !html.startsWith('<p>') && !html.startsWith('<div class="code-block">')) {
            html = `<p>${html}</p>`;
        }
        
        return html;
    }

    escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }

    processMessageContent(messageDiv) {
        // Highlight code blocks
        messageDiv.querySelectorAll('pre code').forEach(block => {
            if (window.Prism) {
                Prism.highlightElement(block);
            }
        });

        // Render Mermaid diagrams
        messageDiv.querySelectorAll('code.language-mermaid').forEach(block => {
            const preElement = block.parentElement;
            const mermaidContainer = document.createElement('div');
            mermaidContainer.className = 'mermaid';
            mermaidContainer.textContent = block.textContent;
            preElement.replaceWith(mermaidContainer);

            if (window.mermaid) {
                try {
                    mermaid.render(`mermaid-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, mermaidContainer.textContent, (svg) => {
                        mermaidContainer.innerHTML = svg;
                    });
                } catch (e) {
                    mermaidContainer.innerHTML = `Mermaid render error: ${e.message}`;
                }
            }
        });
    }

    setLoading(loading) {
        const sendButton = document.getElementById('send-button');
        const messageInput = document.getElementById('message-input');
        if (loading) {
            sendButton.disabled = true;
            sendButton.innerHTML = '<div class="loading"></div>';
            messageInput.disabled = true;
        } else {
            sendButton.disabled = false;
            sendButton.innerHTML = '<i class="fas fa-paper-plane"></i>';
            messageInput.disabled = false;
            messageInput.focus();
        }
    }

    // Visualization functionality
    async generateVisualization() {
        const topic = document.getElementById('topic-select').value;
        const chartType = document.getElementById('chart-type-select').value;
        const generateBtn = document.getElementById('generate-button');
        const chartContainer = document.getElementById('visualization-output');
        
        console.log('Generating visualization with:', { topic, chartType });
        
        if (!topic) {
            chartContainer.innerHTML = `
                <div class="alert alert-warning">
                    请选择一个知识点
                </div>
            `;
            return;
        }
        
        if (!chartType) {
            chartContainer.innerHTML = `
                <div class="alert alert-warning">
                    请选择一个图表类型
                </div>
            `;
            return;
        }
        
        generateBtn.disabled = true;
        generateBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 生成中...';
        
        // 清除之前的渲染缓存
        if (window.mermaid && window.mermaid.unrender) {
            try {
                const containers = chartContainer.querySelectorAll('.mermaid');
                containers.forEach(container => {
                    if (container.id) {
                        window.mermaid.unrender(container.id);
                    }
                });
            } catch (e) {
                console.warn('Mermaid unrender warning:', e);
            }
        }
        
        try {
            // 将中文图表类型转换为英文
            const chartTypeMapping = {
                '流程图': 'flowchart',
                '类图': 'classDiagram',
                '状态图': 'stateDiagram',
                '关系图': 'erDiagram',
                '用户旅程图': 'journey',
                '甘特图': 'gantt',
                '饼图': 'pie',
                'Git图': 'gitgraph'
            };
            
            const englishChartType = chartTypeMapping[chartType] || 'flowchart';
            
            // 添加时间戳以避免缓存
            const timestamp = Date.now();
            const requestParams = {
                topic: topic,
                chart_type: englishChartType,
                user_id: this.currentUserId || 'web_user',
                timestamp: timestamp
            };
            
            console.log('API Request params:', requestParams);
            
            const response = await this.callBackendAPI('/api/visualization', requestParams);
            
            // 添加调试信息
            console.log('API Response:', response);
            console.log('Response type:', typeof response);
            console.log('Response keys:', Object.keys(response));
            
            // 检查响应结构
            if (response && response.status === 'success' && response.mermaid_code) {
                this.renderVisualization(response.mermaid_code, response.chart_type, response.title, response.description);
            } else {
                // 安全地获取错误信息
                const errorMessage = response && response.message ? response.message : 
                                     response ? JSON.stringify(response) : '未知错误';
                chartContainer.innerHTML = `
                    <div class="alert alert-danger">
                        生成图表失败: ${this.escapeHtml(errorMessage)}
                    </div>
                `;
            }
        } catch (error) {
            console.error('生成可视化图表错误:', error);
            chartContainer.innerHTML = `
                <div class="alert alert-danger">
                    网络连接出现问题，请稍后重试
                </div>
            `;
        } finally {
            generateBtn.disabled = false;
            generateBtn.innerHTML = '<i class="fas fa-magic me-2"></i> 生成可视化图表';
        }
    }

    renderVisualization(chartCode, chartType, chartTitle, chartDescription) {
        const chartContainer = document.getElementById('visualization-output');
        
        try {
            // 确保Mermaid库已初始化
            if (!window.mermaid) {
                console.error('Mermaid library not loaded');
                chartContainer.innerHTML = `<div class="alert alert-danger">Mermaid库未加载，请刷新页面重试</div>`;
                return;
            }

            // 清空容器
            chartContainer.innerHTML = '';

            // 创建内容包装器
            const contentWrapper = document.createElement('div');
            contentWrapper.className = 'visualization-content-wrapper'; 

            // 添加标题
            if (chartTitle) {
                const titleElement = document.createElement('h4');
                titleElement.className = 'chart-title';
                titleElement.textContent = chartTitle;
                contentWrapper.appendChild(titleElement);
            }
            
            // 添加描述
            if (chartDescription) {
                const descElement = document.createElement('p');
                descElement.className = 'chart-description';
                descElement.textContent = chartDescription;
                contentWrapper.appendChild(descElement);
            }
            
            // 创建mermaid容器
            const mermaidContainer = document.createElement('div');
            mermaidContainer.id = `mermaid-container-${Date.now()}`;
            mermaidContainer.className = 'mermaid';
            mermaidContainer.style.visibility = 'hidden';
            
            contentWrapper.appendChild(mermaidContainer);
            chartContainer.appendChild(contentWrapper);

            // 渲染mermaid图表
            const mermaidId = `mermaid-${Date.now()}`;
            
            window.mermaid.render(mermaidId, chartCode)
                 .then(result => {
                     // Mermaid 10.x版本返回对象，10.6.1版本返回字符串
                     let svgContent = '';
                     
                     if (typeof result === 'string') {
                         svgContent = result;
                     } else if (result && typeof result === 'object') {
                         // 可能是 {svg: '...', bindFunctions: [...]}
                         svgContent = result.svg || '';
                     }
                     
                     // 检查SVG内容
                     if (svgContent && svgContent.includes('<svg')) {
                         mermaidContainer.innerHTML = svgContent;
                         mermaidContainer.style.visibility = 'visible';
                         
                         // 添加淡入动画
                         const svgElement = mermaidContainer.querySelector('svg');
                         if (svgElement) {
                             svgElement.style.opacity = '0';
                             svgElement.style.transition = 'opacity 0.5s ease-in-out';
                             setTimeout(() => {
                                 svgElement.style.opacity = '1';
                             }, 100);
                         }
                     } else {
                         throw new Error('Invalid SVG output from Mermaid');
                     }
                 })
                .catch(error => {
                    console.error('Mermaid render error:', error);
                    chartContainer.innerHTML = `<div class="alert alert-danger">渲染图表时出错: ${error.message}</div>`;
                });

        } catch (error) {
            console.error("Error during visualization rendering:", error);
            chartContainer.innerHTML = `<div class="alert alert-danger">渲染图表时出错: ${error.message}</div>`;
        }
    }

    async loadTopics() {
        try {
            const response = await this.callBackendAPI('/api/topics');
            
            if (response.status === 'success') {
                this.topics = response.topics;
                const topicSelect = document.getElementById('topic-select');
                topicSelect.innerHTML = '';
                
                // 添加默认选项
                const defaultOption = document.createElement('option');
                defaultOption.value = '';
                defaultOption.textContent = '请选择知识点';
                defaultOption.disabled = true;
                defaultOption.selected = true;
                topicSelect.appendChild(defaultOption);
                
                response.topics.forEach(topic => {
                    const option = document.createElement('option');
                    option.value = topic;
                    option.textContent = topic;
                    topicSelect.appendChild(option);
                });
                
                // 添加主题描述
                this.addTopicDescriptions();
            } else {
                console.error('加载主题失败:', response.message);
                this.showErrorNotification('加载知识点失败，请刷新页面重试');
            }
        } catch (error) {
            console.error('加载主题错误:', error);
            this.showErrorNotification('网络错误，无法加载知识点');
        }
    }

    addTopicDescriptions() {
        // 为知识点选择器添加描述信息
        const topicDescriptions = {
            '所有权': 'Rust的核心内存管理机制',
            '借用': '在不转移所有权的情况下访问数据',
            '生命周期': '确保引用有效性的机制',
            'Trait系统': 'Rust的接口和泛型编程',
            '错误处理': 'Result和Option类型的使用',
            '闭包': '匿名函数和函数式编程',
            '并发': '线程、通道和同步原语',
            '宏': '元编程和代码生成',
            '模式匹配': 'match表达式和解构',
            '迭代器': '惰性求值和函数式编程'
        };
        
        const topicSelect = document.getElementById('topic-select');
        if (!topicSelect) return;
        
        topicSelect.addEventListener('change', () => {
            const selectedTopic = topicSelect.value;
            const descriptionDiv = document.getElementById('topic-description');
            
            if (descriptionDiv && selectedTopic && topicDescriptions[selectedTopic]) {
                descriptionDiv.textContent = topicDescriptions[selectedTopic];
                descriptionDiv.style.display = 'block';
            } else if (descriptionDiv) {
                descriptionDiv.style.display = 'none';
            }
        });
    }

    async loadChartTypes() {
        try {
            const response = await this.callBackendAPI('/api/chart_types');
            
            if (response.status === 'success') {
                this.chartTypes = response.chart_types;
                const chartSelect = document.getElementById('chart-type-select');
                chartSelect.innerHTML = '';
                
                response.chart_types.forEach(chartType => {
                    const option = document.createElement('option');
                    option.value = chartType;
                    option.textContent = chartType;
                    chartSelect.appendChild(option);
                });
            } else {
                console.error('加载图表类型失败:', response.message);
            }
        } catch (error) {
            console.error('加载图表类型错误:', error);
        }
    }

    // Challenge functionality
    async loadChallenges() {
        try {
            const response = await this.callBackendAPI('/api/challenges', {
                user_id: this.currentUserId || 'web_user'
            });
            
            if (response.status === 'success') {
                // 正确处理challenges数据格式
                this.challenges = response.challenges || {};
                this.progress = response.progress || {};
                this.renderTopicLevels(); // 渲染主题关卡
                this.updateProgress();
            } else {
                console.error('加载关卡失败:', response.message);
                // 如果加载失败，初始化为空对象
                this.challenges = {};
                this.renderTopicLevels();
            }
        } catch (error) {
            console.error('加载关卡错误:', error);
            // 如果发生错误，初始化为空对象
            this.challenges = {};
            this.renderTopicLevels();
        }
    }

    renderChallenges() {
        const challengesGrid = document.getElementById('topicLevels');
        if (!challengesGrid) {
            console.error('topicLevels element not found');
            return;
        }
        
        challengesGrid.innerHTML = '';
        
        // 处理challenges数据结构，支持两种格式：
        // 1. {topic: {title, description, levels: [...]}}
        // 2. [{id, title, description, ...}]
        let challengesArray = [];
        
        if (Array.isArray(this.challenges)) {
            // 格式2：直接是数组
            challengesArray = this.challenges;
        } else if (typeof this.challenges === 'object') {
            // 格式1：对象格式，需要转换为数组
            for (const [topicKey, topicData] of Object.entries(this.challenges)) {
                if (topicData.levels && Array.isArray(topicData.levels)) {
                    // 添加主题信息到每个关卡
                    topicData.levels.forEach(level => {
                        challengesArray.push({
                            ...level,
                            topic: topicData.title || topicKey
                        });
                    });
                }
            }
        }
        
        // 确保我们有数组可以处理
        if (!Array.isArray(challengesArray)) {
            console.error('挑战数据格式不正确:', this.challenges);
            challengesGrid.innerHTML = '<div class="col-12 text-center">加载关卡失败，数据格式不正确</div>';
            return;
        }
        
        // 渲染每个挑战
        challengesArray.forEach(challenge => {
            const isCompleted = this.challengeProgress[challenge.id] || false;
            const isLocked = challenge.locked && !this.hasCompletedPrerequisites(challenge);
            
            const challengeCard = document.createElement('div');
            challengeCard.className = `challenge-card ${isCompleted ? 'completed' : ''} ${isLocked ? 'locked' : ''}`;
            challengeCard.dataset.topic = challenge.topic;
            
            challengeCard.innerHTML = `
                <div class="challenge-icon">
                    <i class="fas ${isCompleted ? 'fa-check-circle' : isLocked ? 'fa-lock' : 'fa-code'}"></i>
                </div>
                <h5>${challenge.title}</h5>
                <p>${challenge.description}</p>
                <div class="challenge-meta">
                    <span class="badge bg-${this.getTopicColor(challenge.topic)}">${this.getTopicName(challenge.topic)}</span>
                    <span class="difficulty">
                        ${this.getDifficultyStars(challenge.difficulty)}
                    </span>
                </div>
            `;
            
            if (!isLocked) {
                challengeCard.addEventListener('click', () => {
                    this.openChallenge(challenge);
                });
            }
            
            challengesGrid.appendChild(challengeCard);
        });
    }

    renderDifficultyStars(difficulty) {
        let stars = '';
        for (let i = 1; i <= 3; i++) {
            stars += `<i class="fas fa-star ${i <= difficulty ? 'active' : ''}"></i>`;
        }
        return stars;
    }

    async startChallenge(challengeId) {
        try {
            const response = await this.callBackendAPI(`/api/challenge/${challengeId}`);
            
            if (response.status === 'success') {
                this.currentChallenge = response.challenge;
                this.showChallengeModal(this.currentChallenge);
            } else {
                this.showNotification('获取挑战详情失败', 'error');
            }
        } catch (error) {
            console.error('获取挑战详情失败:', error);
            this.showNotification('获取挑战详情失败', 'error');
        }
    }

    showChallengeModal(challenge) {
        const modal = document.getElementById('challenge-modal');
        if (!modal) return;
        
        const modalTitle = modal.querySelector('.modal-title');
        const modalBody = modal.querySelector('.modal-body');
        
        if (modalTitle) {
            modalTitle.textContent = challenge.title;
        }
        
        // 处理代码片段数据，支持两种格式：
        // 1. code_snippets: ["snippet1", "snippet2", ...]
        // 2. code_fragments: [{id, code, correct, hint}, ...]
        let codeSnippets = [];
        if (challenge.code_snippets && Array.isArray(challenge.code_snippets)) {
            // 格式1：直接是字符串数组
            codeSnippets = challenge.code_snippets.map((snippet, index) => ({
                id: `snippet_${index}`,
                code: snippet
            }));
        } else if (challenge.code_fragments && Array.isArray(challenge.code_fragments)) {
            // 格式2：对象数组
            codeSnippets = challenge.code_fragments;
        }
        
        // 处理代码模板，支持两种格式：
        // 1. code_template: "一行代码"
        // 2. code_template: ["行1", "行2", ...]
        let codeTemplate = "";
        if (Array.isArray(challenge.code_template)) {
            codeTemplate = challenge.code_template.join("\n");
        } else if (typeof challenge.code_template === "string") {
            codeTemplate = challenge.code_template;
        }
        
        modalBody.innerHTML = `
            <div class="challenge-description">
                <p>${challenge.description}</p>
            </div>
            <div class="challenge-code-container">
                <div class="challenge-code-template">
                    <h4>代码模板</h4>
                    <div class="code-block">
                        <pre><code class="language-rust">${this.escapeHtml(codeTemplate)}</code></pre>
                    </div>
                </div>
                <div class="challenge-code-snippets">
                    <h4>代码片段（拖拽到模板中）</h4>
                    <div class="code-snippets-container" id="code-snippets">
                        ${codeSnippets.map((snippet, index) => `
                            <div class="code-snippet" draggable="true" data-snippet-index="${index}">
                                <pre><code>${this.escapeHtml(snippet.code || snippet)}</code></pre>
                            </div>
                        `).join('')}
                    </div>
                </div>
            </div>
            <div class="challenge-actions">
                <button class="btn btn-secondary" id="reset-challenge">重置</button>
                <button class="btn btn-primary" id="validate-challenge">验证答案</button>
            </div>
        `;
        
        // Show modal
        modal.classList.add('active');
        
        // Initialize drag and drop
        this.initDragAndDrop();
        
        // Add event listeners
        document.getElementById('reset-challenge').addEventListener('click', () => {
            this.resetChallenge();
        });
        
        document.getElementById('validate-challenge').addEventListener('click', () => {
            this.validateChallenge();
        });
    }

    resetChallenge() {
        if (!this.currentChallenge) return;
        
        const modalBody = document.querySelector('#challenge-modal .modal-body');
        const codeSnippetsContainer = modalBody.querySelector('#code-snippets');
        
        // 处理代码片段数据，支持两种格式
        let codeSnippets = [];
        if (this.currentChallenge.code_snippets && Array.isArray(this.currentChallenge.code_snippets)) {
            codeSnippets = this.currentChallenge.code_snippets.map((snippet, index) => ({
                id: `snippet_${index}`,
                code: snippet
            }));
        } else if (this.currentChallenge.code_fragments && Array.isArray(this.currentChallenge.code_fragments)) {
            codeSnippets = this.currentChallenge.code_fragments;
        }
        
        // Reset code snippets
        codeSnippetsContainer.innerHTML = codeSnippets.map((snippet, index) => `
            <div class="code-snippet" draggable="true" data-snippet-index="${index}">
                <pre><code>${this.escapeHtml(snippet.code || snippet)}</code></pre>
            </div>
        `).join('');
        
        // Reset code template
        let codeTemplate = "";
        if (Array.isArray(this.currentChallenge.code_template)) {
            codeTemplate = this.currentChallenge.code_template.join("\n");
        } else if (typeof this.currentChallenge.code_template === "string") {
            codeTemplate = this.currentChallenge.code_template;
        }
        
        const codeTemplateElement = modalBody.querySelector('.challenge-code-template pre code');
        if (codeTemplateElement) {
            codeTemplateElement.textContent = codeTemplate;
        }
        
        // Reinitialize drag and drop
        this.initDragAndDrop();
    }

    async validateChallenge() {
        if (!this.currentChallenge) return;
        
        // Get current code template
        const codeTemplate = document.querySelector('#challenge-modal .challenge-code-template pre code');
        const currentCode = codeTemplate.textContent;
        
        try {
            const response = await this.callBackendAPI('/api/challenge/validate', {
                user_id: this.currentUserId || 'web_user',
                challenge_id: this.currentChallenge.id,
                answers: Array.isArray(currentCode) ? currentCode : [currentCode]
            });
            
            if (response.status === 'success') {
                // 显示验证结果
                const isCorrect = response.correct || false;
                const message = response.message || (isCorrect ? '答案正确！' : '答案不正确，请再试一次。');
                
                // 更新UI显示结果
                this.showValidationResult(isCorrect, message, response.explanation);
                
                // 如果答案正确，更新挑战状态
                if (isCorrect) {
                    this.currentChallenge.completed = true;
                    this.updateProgress();
                    
                    // 延迟关闭模态框并重新加载挑战
                    setTimeout(() => {
                        this.closeChallengeModal();
                        this.loadChallenges(); // Reload challenges to update progress
                    }, 2000);
                }
            } else {
                this.showNotification('验证失败: ' + (response.message || '未知错误'), 'error');
            }
        } catch (error) {
            console.error('验证挑战失败:', error);
            this.showNotification('验证失败', 'error');
        }
    }
    
    showValidationResult(isCorrect, message, explanation) {
        const modalBody = document.querySelector('#challenge-modal .modal-body');
        if (!modalBody) return;
        
        // 查找或创建结果显示区域
        let resultDiv = modalBody.querySelector('.validation-result');
        if (!resultDiv) {
            resultDiv = document.createElement('div');
            resultDiv.className = 'validation-result';
            modalBody.appendChild(resultDiv);
        }
        
        // 设置结果样式和内容
        resultDiv.className = `validation-result ${isCorrect ? 'correct' : 'incorrect'}`;
        resultDiv.innerHTML = `
            <div class="result-header">
                <i class="fas ${isCorrect ? 'fa-check-circle' : 'fa-times-circle'}"></i>
                <h4>${isCorrect ? '回答正确！' : '回答错误'}</h4>
            </div>
            <div class="result-message">${message}</div>
            ${explanation ? `<div class="result-explanation">${explanation}</div>` : ''}
        `;
        
        // 添加样式（如果不存在）
        if (!document.querySelector('#validation-result-styles')) {
            const style = document.createElement('style');
            style.id = 'validation-result-styles';
            style.textContent = `
                .validation-result {
                    margin-top: 20px;
                    padding: 15px;
                    border-radius: 8px;
                    animation: fadeIn 0.3s ease-in-out;
                }
                .validation-result.correct {
                    background-color: #d4edda;
                    border: 1px solid #c3e6cb;
                    color: #155724;
                }
                .validation-result.incorrect {
                    background-color: #f8d7da;
                    border: 1px solid #f5c6cb;
                    color: #721c24;
                }
                .result-header {
                    display: flex;
                    align-items: center;
                    margin-bottom: 10px;
                }
                .result-header i {
                    margin-right: 10px;
                    font-size: 1.2rem;
                }
                .result-header h4 {
                    margin: 0;
                }
                .result-explanation {
                    margin-top: 10px;
                    padding-top: 10px;
                    border-top: 1px solid rgba(0,0,0,0.1);
                }
                @keyframes fadeIn {
                    from { opacity: 0; transform: translateY(-10px); }
                    to { opacity: 1; transform: translateY(0); }
                }
            `;
            document.head.appendChild(style);
        }
    }

    closeChallengeModal() {
        const modal = document.getElementById('challenge-modal');
        if (modal) {
            modal.classList.remove('active');
        }
        this.currentChallenge = null;
    }

    initDragAndDrop() {
        const codeSnippets = document.querySelectorAll('.code-snippet');
        const codeTemplate = document.querySelector('.challenge-code-template pre code');
        
        if (!codeTemplate) return;
        
        codeSnippets.forEach(snippet => {
            snippet.addEventListener('dragstart', (e) => {
                e.dataTransfer.setData('text/plain', snippet.textContent);
                e.dataTransfer.setData('snippet-index', snippet.getAttribute('data-snippet-index'));
                if (snippet.classList) {
                    snippet.classList.add('dragging');
                }
            });
            
            snippet.addEventListener('dragend', () => {
                if (snippet.classList) {
                    snippet.classList.remove('dragging');
                }
            });
        });
        
        codeTemplate.addEventListener('dragover', (e) => {
            e.preventDefault();
            if (codeTemplate.classList) {
                codeTemplate.classList.add('drag-over');
            }
        });
        
        codeTemplate.addEventListener('dragleave', () => {
            if (codeTemplate.classList) {
                codeTemplate.classList.remove('drag-over');
            }
        });
        
        codeTemplate.addEventListener('drop', (e) => {
            e.preventDefault();
            if (codeTemplate.classList) {
                codeTemplate.classList.remove('drag-over');
            }
            
            const snippetText = e.dataTransfer.getData('text/plain');
            const snippetIndex = e.dataTransfer.getData('snippet-index');
            
            // Simple insertion at cursor position
            const textContent = codeTemplate.textContent;
            const selection = window.getSelection();
            let position = textContent.length;
            
            if (selection.rangeCount > 0) {
                const range = selection.getRangeAt(0);
                const preCaretRange = range.cloneRange();
                preCaretRange.selectNodeContents(codeTemplate);
                preCaretRange.setEnd(range.startContainer, range.startOffset);
                position = preCaretRange.toString().length;
            }
            
            const newText = textContent.substring(0, position) + 
                           '\n' + snippetText + '\n' + 
                           textContent.substring(position);
            
            codeTemplate.textContent = newText;
            
            // Remove the used snippet
            const usedSnippet = document.querySelector(`.code-snippet[data-snippet-index="${snippetIndex}"]`);
            if (usedSnippet) {
                usedSnippet.remove();
            }
        });
    }

    showNotification(message, type) {
        // Create notification element
        const notification = document.createElement('div');
        notification.className = `notification notification-${type}`;
        notification.textContent = message;
        
        // Add to page
        document.body.appendChild(notification);
        
        // Show notification
        setTimeout(() => {
            notification.classList.add('show');
        }, 10);
        
        // Hide after 3 seconds
        setTimeout(() => {
            notification.classList.remove('show');
            setTimeout(() => {
                document.body.removeChild(notification);
            }, 300);
        }, 3000);
    }

    showSuccessNotification(message) {
        this.showNotification(message, 'success');
    }

    showErrorNotification(message) {
        this.showNotification(message, 'error');
    }

    addDownloadButton(container, svgContent, filename) {
        if (!container) return;
        
        const downloadSection = document.createElement('div');
        downloadSection.className = 'download-section mt-3';
        
        // Download as SVG
        const downloadSvgBtn = document.createElement('button');
        downloadSvgBtn.className = 'btn btn-outline-primary me-2';
        downloadSvgBtn.innerHTML = '<i class="fas fa-download me-2"></i>下载SVG';
        
        downloadSvgBtn.addEventListener('click', () => {
            const blob = new Blob([svgContent], { type: 'image/svg+xml' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `${filename}.svg`;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        });
        
        // Download as PNG
        const downloadPngBtn = document.createElement('button');
        downloadPngBtn.className = 'btn btn-outline-primary me-2';
        downloadPngBtn.innerHTML = '<i class="fas fa-image me-2"></i>下载PNG';
        
        downloadPngBtn.addEventListener('click', () => {
            // Create canvas from SVG
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            const img = new Image();
            
            img.onload = () => {
                canvas.width = img.width;
                canvas.height = img.height;
                ctx.drawImage(img, 0, 0);
                
                canvas.toBlob((blob) => {
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = `${filename}.png`;
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                    URL.revokeObjectURL(url);
                }, 'image/png');
            };
            
            const svgBlob = new Blob([svgContent], { type: 'image/svg+xml;charset=utf-8' });
            const svgUrl = URL.createObjectURL(svgBlob);
            img.src = svgUrl;
        });
        
        downloadSection.appendChild(downloadSvgBtn);
        downloadSection.appendChild(downloadPngBtn);
        container.appendChild(downloadSection);
    }

    initMobileMenu() {
        const mobileMenuToggle = document.querySelector('.mobile-menu-toggle');
        const sidebar = document.querySelector('.sidebar');
        
        if (mobileMenuToggle && sidebar) {
            mobileMenuToggle.addEventListener('click', () => {
                sidebar.classList.toggle('active');
            });
            
            // Close sidebar when clicking outside
            document.addEventListener('click', (e) => {
                if (!sidebar.contains(e.target) && !mobileMenuToggle.contains(e.target)) {
                    sidebar.classList.remove('active');
                }
            });
        }
    }

    initAnimations() {
        // 初始化动画效果
        // 添加页面加载动画
        document.addEventListener('DOMContentLoaded', () => {
            document.body.classList.add('loaded');
            
            // 为知识卡片添加动画
            const cards = document.querySelectorAll('.knowledge-card');
            cards.forEach((card, index) => {
                setTimeout(() => {
                    card.classList.add('animate-in');
                }, index * 100);
            });
            
            // 为侧边栏问题添加动画
            const questions = document.querySelectorAll('.sidebar-question');
            questions.forEach((question, index) => {
                setTimeout(() => {
                    question.classList.add('animate-in');
                }, index * 50);
            });
        });
        
        // Add entrance animations to elements
        const animateElements = document.querySelectorAll('.animate-on-scroll');
        
        const observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    entry.target.classList.add('animated');
                }
            });
        }, { threshold: 0.1 });
        
        animateElements.forEach(element => {
            observer.observe(element);
        });
    }

    animateTabContent(tabElement) {
        if (!tabElement) return;
        
        // Add animation class
        tabElement.classList.add('tab-content-animate');
        
        // Remove animation class after animation completes
        setTimeout(() => {
            tabElement.classList.remove('tab-content-animate');
        }, 300);
    }

    showWelcomeMessage() {
        const welcomeMessage = `
# 欢迎来到 Rust 学习智能体！

我是你的 Rust 学习助手，可以帮助你：

## 🤖 智能问答
- 解答 Rust 相关问题
- 提供代码示例和解释
- 深入讲解 Rust 概念

## 📊 知识可视化
- 生成 Rust 概念的图表
- 可视化 Rust 的复杂概念
- 支持多种图表类型

## 🎯 代码闯关
- 通过拖拽代码片段完成挑战
- 学习 Rust 的所有权和借用规则
- 逐步提升编程技能

## 💡 使用提示
- 点击侧边栏的问题可以快速提问
- 点击知识卡片可以了解相关主题
- 在代码编辑器中按 Shift+Enter 可以换行

选择一个标签页开始学习吧！
        `;
        
        this.addMessage(welcomeMessage, 'assistant');
    }

    initMermaid() {
        // 初始化Mermaid库
        if (window.mermaid) {
            window.mermaid.initialize({
                startOnLoad: false,
                theme: 'default',
                securityLevel: 'loose',
                fontFamily: 'Arial, sans-serif',
                flowchart: {
                    useMaxWidth: true,
                    htmlLabels: true,
                    curve: 'cardinal'
                },
                themeVariables: {
                    primaryColor: '#ce422b',
                    primaryTextColor: '#333',
                    primaryBorderColor: '#ce422b',
                    lineColor: '#ce422b',
                    secondaryColor: '#f8f9fa',
                    tertiaryColor: '#fff3e0',
                    background: '#ffffff',
                    mainBkg: '#ffffff',
                    secondBkg: '#f8f9fa',
                    tertiaryBkg: '#fff3e0'
                }
            });
            console.log('Mermaid library initialized successfully');
        } else {
            console.error('Mermaid library not found');
        }
    }

    loadUserSession() {
        // Try to load user session from localStorage
        const savedUserId = localStorage.getItem('rust_learning_user_id');
        if (savedUserId) {
            this.currentUserId = savedUserId;
        } else {
            // Generate new user ID
            this.currentUserId = 'user_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
            localStorage.setItem('rust_learning_user_id', this.currentUserId);
        }
        
        // Load session ID
        const savedSessionId = localStorage.getItem('rust_learning_session_id');
        if (savedSessionId) {
            this.sessionId = savedSessionId;
        } else {
            // Generate new session ID
            this.sessionId = 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
            localStorage.setItem('rust_learning_session_id', this.sessionId);
        }
    }



    hasCompletedPrerequisites(challenge) {
        if (!challenge.prerequisites || challenge.prerequisites.length === 0) {
            return true;
        }
        
        return challenge.prerequisites.every(prereqId => 
            this.challengeProgress[prereqId] || false
        );
    }

    getTopicColor(topic) {
        const colors = {
            'ownership': 'primary',
            'borrowing': 'success',
            'lifetimes': 'info',
            'traits': 'warning',
            'error-handling': 'danger',
            'concurrency': 'secondary',
            'macros': 'dark',
            'async': 'light',
            '所有权': 'primary',
            '借用检查器': 'success',
            'Trait系统': 'warning',
            '错误处理': 'danger',
            '闭包': 'info',
            '并发': 'secondary',
            '宏': 'dark',
            '模式匹配': 'warning',
            '迭代器': 'info'
        };
        return colors[topic] || 'primary';
    }

    getTopicName(topic) {
        const names = {
            'ownership': '所有权',
            'borrowing': '借用',
            'lifetimes': '生命周期',
            'traits': 'Trait',
            'error-handling': '错误处理',
            'concurrency': '并发',
            'macros': '宏',
            'async': '异步',
            '所有权': '所有权',
            '借用检查器': '借用',
            'Trait系统': 'Trait',
            '错误处理': '错误处理',
            '闭包': '闭包',
            '并发': '并发',
            '宏': '宏',
            '模式匹配': '模式匹配',
            '迭代器': '迭代器'
        };
        return names[topic] || topic;
    }

    getDifficultyStars(difficulty) {
        let stars = '';
        for (let i = 1; i <= 5; i++) {
            stars += `<i class="fas fa-star ${i <= difficulty ? 'active' : ''}"></i>`;
        }
        return stars;
    }

    filterChallenges(topic) {
        this.currentTopic = topic;
        const challengeCards = document.querySelectorAll('.challenge-card');
        
        challengeCards.forEach(card => {
            if (topic === 'all' || card.dataset.topic === topic) {
                card.style.display = '';
            } else {
                card.style.display = 'none';
            }
        });
    }

    openChallenge(challenge) {
        this.currentChallenge = challenge;
        const modal = document.getElementById('challenge-modal');
        const title = document.getElementById('challenge-title');
        const instruction = document.getElementById('challenge-instruction');
        const workspace = document.getElementById('challenge-workspace');
        const feedback = document.getElementById('challenge-feedback');
        const validateBtn = document.getElementById('validate-btn');
        const nextBtn = document.getElementById('next-challenge-btn');
        
        title.textContent = challenge.title;
        instruction.innerHTML = `<p>${challenge.instruction}</p>`;
        feedback.style.display = 'none';
        nextBtn.style.display = 'none';
        validateBtn.style.display = 'block';
        
        // Create drag and drop workspace
        this.createChallengeWorkspace(workspace, challenge);
        
        modal.style.display = 'flex';
    }

    createChallengeWorkspace(workspace, challenge) {
        workspace.innerHTML = '';
        
        // Create code snippets area
        const snippetsArea = document.createElement('div');
        snippetsArea.className = 'code-snippets';
        snippetsArea.innerHTML = '<h5>代码片段</h5>';
        
        const snippetsList = document.createElement('div');
        snippetsList.className = 'snippets-list';
        
        challenge.code_snippets.forEach((snippet, index) => {
            const snippetElement = document.createElement('div');
            snippetElement.className = 'code-snippet';
            snippetElement.draggable = true;
            snippetElement.dataset.id = snippet.id;
            snippetElement.textContent = snippet.code;
            
            snippetElement.addEventListener('dragstart', (e) => {
                e.dataTransfer.setData('text/plain', snippet.id);
                e.dataTransfer.effectAllowed = 'copy';
            });
            
            snippetsList.appendChild(snippetElement);
        });
        
        snippetsArea.appendChild(snippetsList);
        workspace.appendChild(snippetsArea);
        
        // Create code template area
        const templateArea = document.createElement('div');
        templateArea.className = 'code-template';
        templateArea.innerHTML = '<h5>代码模板</h5>';
        
        const templateContainer = document.createElement('div');
        templateContainer.className = 'template-container';
        templateContainer.innerHTML = challenge.template;
        
        // Add drop zones to the template
        const placeholders = templateContainer.querySelectorAll('.drop-zone');
        placeholders.forEach(placeholder => {
            placeholder.addEventListener('dragover', (e) => {
                e.preventDefault();
                e.dataTransfer.dropEffect = 'copy';
                if (placeholder.classList) {
                    placeholder.classList.add('drag-over');
                }
            });
            
            placeholder.addEventListener('dragleave', () => {
                if (placeholder.classList) {
                    placeholder.classList.remove('drag-over');
                }
            });
            
            placeholder.addEventListener('drop', (e) => {
                e.preventDefault();
                const snippetId = e.dataTransfer.getData('text/plain');
                const snippet = challenge.code_snippets.find(s => s.id === snippetId);
                
                if (snippet && snippet.code) {
                    placeholder.textContent = snippet.code;
                    placeholder.dataset.filled = 'true';
                    if (placeholder.classList) {
                        placeholder.classList.remove('drag-over');
                    }
                }
            });
        });
        
        templateArea.appendChild(templateContainer);
        workspace.appendChild(templateArea);
    }



    updateProgress() {
        const totalChallenges = Object.keys(this.challengeProgress).length;
        const completedChallenges = Object.values(this.challengeProgress).filter(Boolean).length;
        const progressPercent = totalChallenges > 0 ? (completedChallenges / totalChallenges) * 100 : 0;
        
        const overallProgressText = document.getElementById('overall-progress-text');
        if (overallProgressText) {
            overallProgressText.textContent = `${completedChallenges}/${totalChallenges} 完成`;
        }
        const overallProgressBar = document.getElementById('overall-progress-bar');
        if (overallProgressBar) {
            overallProgressBar.style.width = `${progressPercent}%`;
        }
        
        // 也更新userProgress元素（如果存在）
        const userProgress = document.getElementById('userProgress');
        if (userProgress) {
            userProgress.textContent = `${completedChallenges}/${totalChallenges} 完成`;
        }
    }

    showWelcomeMessage() {
        // 显示欢迎消息，但不添加到聊天容器
        // 欢迎界面已在HTML中定义
    }
    
    loadUserSession() {
        this.currentUserId = 'web_user';
    }
    
    // ================ 挑战系统方法 ================
    
    // 初始化挑战系统
    initChallenges() {
        // 如果存在挑战相关的DOM元素，则初始化挑战功能
        const challengesTab = document.getElementById('challenges-tab');
        if (challengesTab) {
            this.loadChallenges();
            this.initDragAndDropForChallenges();
        }
    }

    
    // 渲染主题关卡
    renderTopicLevels() {
        const container = document.getElementById('topicLevels');
        if (!container || !this.challenges) return;
        
        container.innerHTML = '';

        Object.entries(this.challenges).forEach(([topicId, topicData]) => {
            const card = this.createTopicCard(topicId, topicData);
            container.appendChild(card);
        });
    }
    
    // 创建主题卡片
    createTopicCard(topicId, topicData) {
        const card = document.createElement('div');
        card.className = 'topic-card';
        card.onclick = () => this.enterTopic(topicId);

        const iconClass = topicId === 'ownership' ? 'topic-ownership' : 'topic-borrowing';
        const icon = topicData.icon || (topicId === 'ownership' ? '🔑' : '🔗');

        const levelsHtml = topicData.levels.map((level, index) => {
            const status = this.getLevelStatus(topicId, index);
            return `<div class="level-dot ${status}">${index + 1}</div>`;
        }).join('');

        card.innerHTML = `
            <div class="topic-header">
                <div class="topic-icon ${iconClass}">${icon}</div>
                <div class="topic-info">
                    <h3>${topicData.title}</h3>
                    <p>${topicData.description}</p>
                </div>
            </div>
            <div class="levels-preview">
                ${levelsHtml}
            </div>
        `;

        return card;
    }
    
    // 获取关卡状态
    getLevelStatus(topicId, levelIndex) {
        if (levelIndex === 0) return 'completed';
        if (levelIndex === 1) return 'current';
        return 'locked';
    }
    
    // 进入主题
    enterTopic(topicId) {
        this.currentTopicForChallenge = topicId;
        this.currentLevelIndex = 0;
        this.loadChallenge();
    }
    
    // 加载挑战
    async loadChallenge() {
        if (!this.challenges || !this.currentTopicForChallenge) return;

        const topic = this.challenges[this.currentTopicForChallenge];
        const level = topic.levels[this.currentLevelIndex];

        if (!level) return;

        this.currentChallenge = level;

        // 更新UI
        const challengeTitle = document.getElementById('challengeTitle');
        if (challengeTitle) {
            challengeTitle.textContent = level.title;
        }
        const levelSelector = document.getElementById('levelSelector');
        if (levelSelector) {
            levelSelector.style.display = 'none';
        }
        const challengeView = document.getElementById('challengeView');
        if (challengeView) {
            challengeView.style.display = 'block';
        }
        const backBtn = document.getElementById('backBtn');
        if (backBtn) {
            backBtn.style.display = 'block';
        }
        const pageTitle = document.getElementById('page-title');
        if (pageTitle) {
            pageTitle.textContent = '正在挑战';
        }

        // 更新进度信息
        this.updateChallengeProgress();

        // 渲染挑战内容
        this.renderChallengeContent(level);
    }
    
    // 更新挑战进度
    updateChallengeProgress() {
        if (!this.challenges || !this.currentTopicForChallenge) return;
        
        const topic = this.challenges[this.currentTopicForChallenge];
        const totalLevels = topic.levels.length;
        
        const currentLevelNum = document.getElementById('currentLevelNum');
        if (currentLevelNum) {
            currentLevelNum.textContent = this.currentLevelIndex + 1;
        }
        const totalLevelsElement = document.getElementById('totalLevels');
        if (totalLevelsElement) {
            totalLevelsElement.textContent = totalLevels;
        }
        const completionRate = document.getElementById('completionRate');
        if (completionRate) {
            completionRate.textContent = Math.round((this.currentLevelIndex / totalLevels) * 100) + '%';
        }
    }
    
    // 渲染挑战内容
    renderChallengeContent(level) {
        // 渲染任务说明
        const instructionsContainer = document.getElementById('challengeInstructions');
        if (instructionsContainer) {
            const instructionText = level.description || level.instruction || '请完成下面的代码填空挑战';
            instructionsContainer.innerHTML = `
                <div class="instruction-text">
                    <h6><i class="fas fa-lightbulb me-2"></i>任务描述</h6>
                    <p>${instructionText}</p>
                </div>
                <div class="difficulty-info">
                    <span class="difficulty-badge difficulty-${level.difficulty}">
                        难度: ${'★'.repeat(level.difficulty)}${'☆'.repeat(5-level.difficulty)}
                    </span>
                </div>
            `;
        }
        
        // 渲染代码模板
        this.renderCodeTemplate(level.code_template);
        
        // 渲染代码片段
        this.renderFragments(level.code_fragments);
    }
    
    // 渲染代码模板
    renderCodeTemplate(template) {
        const container = document.getElementById('codeTemplate');
        if (!container) return;
        
        container.innerHTML = '';

        template.forEach((line, index) => {
            const lineDiv = document.createElement('div');
            lineDiv.className = 'code-line';
            
            // 检查是否有空白处
            const hasBlank = line.includes('_____');
            
            if (hasBlank) {
                const parts = line.split('_____');
                lineDiv.innerHTML = `
                    <span class="code-line-number">${index + 1}</span>
                    ${parts[0]}
                    <span class="blank-spot" data-position="0" ondrop="window.rustApp.dropFragment(event)" ondragover="window.rustApp.allowDrop(event)">拖拽代码</span>
                    ${parts[1] || ''}
                `;
            } else {
                lineDiv.innerHTML = `
                    <span class="code-line-number">${index + 1}</span>
                    ${line}
                `;
            }
            
            container.appendChild(lineDiv);
        });
    }
    
    // 渲染代码片段
    renderFragments(fragments) {
        const container = document.getElementById('fragmentList');
        if (!container) return;
        
        container.innerHTML = '';

        fragments.forEach(fragment => {
            const fragmentDiv = document.createElement('div');
            fragmentDiv.className = 'fragment-item';
            fragmentDiv.draggable = true;
            fragmentDiv.textContent = fragment.code;
            fragmentDiv.dataset.id = fragment.id;
            fragmentDiv.dataset.correct = fragment.correct;
            fragmentDiv.dataset.hint = fragment.hint;

            fragmentDiv.ondragstart = (e) => {
                e.dataTransfer.setData('text/plain', fragment.code);
                e.dataTransfer.setData('text/fragmentId', fragment.id);
                fragmentDiv.classList.add('dragging');
            };

            fragmentDiv.ondragend = () => {
                fragmentDiv.classList.remove('dragging');
            };

            container.appendChild(fragmentDiv);
        });
    }
    
    // 拖拽处理方法
    allowDrop(e) {
        e.preventDefault();
        e.target.classList.add('drag-over');
    }
    
    dropFragment(e) {
        e.preventDefault();
        e.target.classList.remove('drag-over');
        
        const code = e.dataTransfer.getData('text/plain');
        const fragmentId = e.dataTransfer.getData('text/fragmentId');
        
        if (e.target.classList.contains('blank-spot')) {
            e.target.textContent = code;
            e.target.dataset.fragmentId = fragmentId;
            e.target.classList.add('filled');
            
            // 禁用已使用的片段
            const fragmentItem = document.querySelector(`[data-id="${fragmentId}"]`);
            if (fragmentItem) {
                fragmentItem.classList.add('used');
                fragmentItem.draggable = false;
            }
        }
    }
    
    // 检查答案
    checkAnswer() {
        if (!this.currentChallenge) return;

        const blanks = document.querySelectorAll('.blank-spot.filled');
        const answers = Array.from(blanks).map(blank => blank.textContent.trim());
        const correctAnswers = this.currentChallenge.correct_answer;

        // 检查答案是否正确
        const isCorrect = JSON.stringify(answers.sort()) === JSON.stringify(correctAnswers.sort());

        if (isCorrect) {
            this.showResult(true, this.currentChallenge.explanation);
        } else {
            this.showResult(false);
        }
    }
    
    // 显示结果
    showResult(isCorrect, explanation = '') {
        const resultHtml = isCorrect 
            ? `
                <div class="result-success">
                    <div class="result-icon">🎉</div>
                    <h4>恭喜通过！</h4>
                    <p>你成功完成了这个挑战！</p>
                    ${explanation ? `<div class="explanation"><h6>解释：</h6><p>${explanation}</p></div>` : ''}
                    <button class="btn btn-success" onclick="window.rustApp.nextLevel()">
                        <i class="fas fa-arrow-right me-2"></i>
                        下一关
                    </button>
                </div>
            `
            : `
                <div class="result-error">
                    <div class="result-icon">😔</div>
                    <h4>再试一次！</h4>
                    <p>答案不正确，看看提示再试试吧！</p>
                    <button class="btn btn-primary" onclick="document.querySelector('.result-modal').style.display='none'">
                        <i class="fas fa-redo me-2"></i>
                        重新尝试
                    </button>
                </div>
            `;
        
        // 创建一个模态框来显示结果
        let modal = document.querySelector('.result-modal');
        if (!modal) {
            modal = document.createElement('div');
            modal.className = 'result-modal';
            modal.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.5);
                display: flex;
                justify-content: center;
                align-items: center;
                z-index: 9999;
            `;
            document.body.appendChild(modal);
        }
        
        modal.innerHTML = `
            <div class="result-content" style="
                background: white;
                padding: 2rem;
                border-radius: 10px;
                text-align: center;
                max-width: 400px;
                margin: 0 20px;
            ">
                ${resultHtml}
            </div>
        `;
        
        modal.style.display = 'flex';
        
        // 点击模态框外部关闭
        modal.onclick = (e) => {
            if (e.target === modal) {
                modal.style.display = 'none';
            }
        };
    }
    
    // 下一关
    nextLevel() {
        if (!this.challengesData || !this.currentTopicForChallenge) return;

        const topic = this.challengesData[this.currentTopicForChallenge];
        if (this.currentLevelIndex < topic.levels.length - 1) {
            this.currentLevelIndex++;
            this.loadChallenge();
        } else {
            this.exitChallenge();
        }
        
        // 关闭结果模态框
        const modal = document.querySelector('.result-modal');
        if (modal) {
            modal.style.display = 'none';
        }
    }
    
    // 重置挑战
    resetChallenge() {
        if (!this.currentChallenge) return;

        // 清除所有填充的空白
        const blanks = document.querySelectorAll('.blank-spot.filled');
        blanks.forEach(blank => {
            blank.textContent = '拖拽代码';
            blank.classList.remove('filled');
            delete blank.dataset.fragmentId;
        });

        // 重新启用所有片段
        const fragments = document.querySelectorAll('.fragment-item.used');
        fragments.forEach(fragment => {
            fragment.classList.remove('used');
            fragment.draggable = true;
        });
    }
    
    // 退出挑战
    exitChallenge() {
        document.getElementById('challengeView').style.display = 'none';
        document.getElementById('levelSelector').style.display = 'block';
        document.getElementById('backBtn').style.display = 'none';
        document.getElementById('page-title').textContent = '选择关卡';
        this.currentChallenge = null;
        this.currentTopicForChallenge = null;
        this.currentLevelIndex = 0;
    }
    
    // 初始化挑战拖拽功能
    initDragAndDropForChallenges() {
        // 拖拽相关的全局函数
        window.allowDrop = (e) => this.allowDrop(e);
        window.dropFragment = (e) => this.dropFragment(e);
        window.checkAnswer = () => this.checkAnswer();
        window.resetChallenge = () => this.resetChallenge();
        window.exitChallenge = () => this.exitChallenge();
    }
}

// Global functions for challenge modal
function closeChallenge() {
    document.getElementById('challenge-modal').style.display = 'none';
}

function validateChallenge() {
    if (window.rustApp) {
        window.rustApp.validateChallenge();
    }
}

// Tab switching logic
document.addEventListener('DOMContentLoaded', () => {
    window.rustApp = new RustLearningApp();
    
    // 创建全局app实例，以便在HTML中访问
    window.app = window.rustApp;
    
    const tabButtons = document.querySelectorAll('.tab-button');
    const tabContents = document.querySelectorAll('.tab-content');
    
    tabButtons.forEach(button => {
        button.addEventListener('click', () => {
            const tabId = button.dataset.tab;

            // Remove active class from all tabs and contents
            tabButtons.forEach(btn => btn.classList.remove('active'));
            tabContents.forEach(content => content.classList.remove('active'));

            // Add active class to clicked button and corresponding content
            button.classList.add('active');
            
            // Find the corresponding tab content
            const targetTab = document.getElementById(`${tabId}-tab`);
            if (targetTab) {
                targetTab.classList.add('active');
            }
        });
    });
    
    // Initialize the first tab as active
    if (tabButtons.length > 0 && tabContents.length > 0) {
        tabButtons[0].classList.add('active');
        tabContents[0].classList.add('active');
    }
});